package san.java.day14;

import java.lang.reflect.Constructor;

/**
 * 利用反射来创建对象
 *  *  创建Class类对象(四种方法):
 *  *      1. 若已知具体的类,通过类的属性获取
 *  *          Class clazz = String.class;
 *  *      2. 已知某个类的实例,调用该实例的getClass()方法获取Class对象
 *  *          Class clazz = "axc".getClass();
 *  *      3. 已知一个类的全类名,且该类在类搜索路径下,可通过Class类的静态方法forName()获取,
 *  *          可能抛出ClassNotFoundException的异常
 *  *          Class clazz = Class.forName("java.lang.String");
 *  *      4. 其他方式:
 *  *          ClassLoader cl = this.getClass().getClassLoader();
 *  *          class clazz = cl.loadClass("类的全类名");
 */

public class Reflect_05 {

    public static void testCreateObjectByReflect() throws Exception {
        Class<?> dogClass = Class.forName("san.java.day14.GoldenDog");

        // 1. newInstance() 相当于调用无参构造
        Object o = dogClass.newInstance();
        GoldenDog goldenDog = (GoldenDog) o;

        // 2. 使用 Constructor<?> 来构造
        Constructor<?> constructor = dogClass.getConstructor(String.class, int.class);
        GoldenDog small_black = (GoldenDog) constructor.newInstance("Small Black", 1);
        small_black.showInfo();

        // 3. 通过反射方式可以强制调用私有构造
        // 不能直接newInstance()调用
        // privateConstructor.setAccessible(true);  // 解除私有
        Constructor<?> privateConstructor = dogClass.getDeclaredConstructor(String.class);
        privateConstructor.setAccessible(true);  // 解除私有
        GoldenDog aPrivate = (GoldenDog) privateConstructor.newInstance("private");

        System.out.println(aPrivate.getName());

    }

    public static void main(String[] args) {
        try {
            testCreateObjectByReflect();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
